use wd_run::{ExecManager, CmdInfo, AsyncEvent, Context, KE_ARGS};
use std::sync::Arc;
use std::collections::HashMap;
use std::str::FromStr;

use super::load_lua::MyLuaManage;
use crate::models::test::test_lua::TestModule;
use tokio::sync::RwLock;
use std::ops::DerefMut;
use crate::models::http::routing::HttpModule;
use crate::models::crypto::routing::CryptoModule;
use crate::models::func::routing::FuncModule;

lazy_static::lazy_static! {
    // pub static ref http_client:Client<HttpConnector> = Client::new();
    pub static ref SENDRECV:(crossbeam::Sender<MyLuaManage>, crossbeam::Receiver<MyLuaManage>) = crossbeam::channel::bounded(2);
}

pub const TASKS: &'static str = "--tasks";
pub const LOGLEVEL: &'static str = "--log";
pub const SCRIPT_FILE: &'static str = "--file";
pub const MODELS:&'static str = "--mods";


#[derive(Default,Debug,Clone)]
pub struct ServerEntity{
    pub args: Arc<RwLock<HashMap<String,String>>>,
}
impl ServerEntity{
    fn get_cmd_run() ->CmdInfo{
        let mut info = CmdInfo::new("run", "", "run server");
        info.set_flag(LOGLEVEL,"debug","log level[debug info warn error panic]");
        info.set_flag(TASKS,"1","number of tasks run");
        info.set_flag(SCRIPT_FILE,"./script/main.lua","lua script file path");
        info.set_flag(MODELS,"test,http,crypto,func","add modules to the Lua environment");
        info
    }
    fn get_cmd_test() ->CmdInfo{
        let mut info = CmdInfo::new("test", "", "test server");
        info.set_flag("-tasks","1","number of threads running the service");
        info.set_flag("--log","debug","log level[debug info warn error panic]");
        info
    }
    //解析输入参数
    async fn parse_args(&self,ctx: Arc<Context>){
        let args = ctx.get_value::<&str, HashMap<String, String>>(&KE_ARGS).unwrap();
        let log_level = args.get(LOGLEVEL).unwrap();
        wd_log::set_level(wd_log::Level::from(log_level));
        wd_log::set_prefix("RusTLua");
        wd_log::show_time(false);
        wd_log::show_file_line(false);
        wd_log::log_debug_ln!("args parse success");
        let mut self_args = self.args.write().await;
        let self_args = self_args.deref_mut();
        *self_args = args;
    }
    #[allow(non_fmt_panic)]
    async fn get_args(&self,key:&str)->String{
        let args = self.args.read().await;
        match args.get(&key.to_string()) {
            None=>{
                wd_log::log_panic!("不识别的命令参数[{}]",key)
            }
            Some(s)=>s.clone(),
        }
    }
    //获取线程个数
    async fn test(&self){
        let mut mlg = MyLuaManage::build(1);
        mlg.register(|lua|{
            lua.globals().set("test_struct", TestModule {
                describe:"rust ->   hello".to_string(),
            }).unwrap();
            // let test_func = lua.create_async_function(test).unwrap();
            // lua.globals().set("test_show_name",test_func).unwrap();
            let test_show = lua.create_async_function(|_lua, uri: String| async move {
                println!("{}",uri);Ok(())
            }).unwrap();
            lua.globals().set("fetch_url",test_show).unwrap();
        });
        mlg.load_from_file("./script/test.lua").unwrap();
        SENDRECV.0.send(mlg).expect("send MyLuaManage error");
    }
    async fn run(&self){
        let tasks = self.get_args(TASKS).await;
        let tasks = u32::from_str(tasks.as_str()).expect("获取任务数错误");
        let mut mlg = MyLuaManage::build(tasks);
        //加载模块
        let mods = self.get_args(MODELS).await;
        let mods:Vec<&str>  = mods.split(",").collect();
        for module in mods {
            match module {
                "test"=>{
                    mlg.register(|lua|{
                        lua.globals().set("test",TestModule::new()).expect("设置TestModule到lua.globals错误");
                    })
                }
                "http"=>{
                    mlg.register(|lua|{
                        lua.globals().set("http", HttpModule::default()).expect("设置HttpModule到lua.globals错误");
                    })
                }
                "crypto"=>{
                    mlg.register(|lua|{
                        lua.globals().set("crypto", CryptoModule::default()).expect("设置CryptoModule到lua.globals错误");
                    })
                }
                "func"=>{
                    mlg.register(|lua|{
                        lua.globals().set("func", FuncModule::default()).expect("设置FuncModule到lua.globals错误");
                    })
                }
                _=> {
                    wd_log::log_error_ln!("不支持的module[{}]",module);
                    continue
                },
            }
            wd_log::log_info_ln!("从配置中加载模块[{}]成功",module)
        }
        let script_path = self.get_args(SCRIPT_FILE).await;
        if let Err(e) = mlg.load_from_file(script_path.as_str()) {
            wd_log::log_error_ln!("脚本文件[{}]载入失败,error=\"{}\"",script_path,e.to_string())
        }else{
            wd_log::log_info_ln!("脚本文件载入成功,path=\"{}\"",script_path)
        }
        SENDRECV.0.send(mlg).expect("send MyLuaManage error");
    }
}
#[wd_run::event_trait]
impl AsyncEvent for ServerEntity{
    async fn handle(&self, ctx: Arc<Context>) {
        self.parse_args(ctx.clone()).await;
        let cmd = ctx.get_msg::<String>().unwrap();
        wd_log::log_info_ln!("The service currently runs the command {}",cmd.as_str());
        match cmd.as_str(){
            "test"=> self.test().await,
            "run"=> self.run().await,
            _ => wd_log::log_error_ln!("未知的命令({})",cmd.as_str())
        };
        // std::process::exit(1);
    }
}
#[allow(non_fmt_panic)]
pub async fn run(){
    let server = ServerEntity::default();
    let mut manage = ExecManager::new().await;

    manage.registered(server.clone(),ServerEntity::get_cmd_run());
    manage.registered(server,ServerEntity::get_cmd_test());

    // cmd.async_run().await.expect("wd_run 运行失败");
    wd_log::res_panic!(manage.async_run().await);
}